import React, {
  PureComponent, useContext, useEffect, useRef, useState,
} from 'react'
import {
  Button, Form, Input, message, Modal, Popconfirm, Select, Tooltip, TreeSelect,
} from 'antd'
import list2tree from 'list2tree'
import { DownOutlined, ExclamationCircleFilled } from '@ant-design/icons'
import {
  BreadcrumbBar,
  HufuTreeTitle,
  InputSearch,
  ProTable,
  ProTableOperate,
  ProTableOptions,
  ProTree,
  searchTreeListByName,
} from '@/components'
import {
  addCatalog, addIndexVersion, delCatalog, delIndex, editCatalog, getDepartList, listCatalog,
} from './api'
import NewIndexModal from './newIndexModal'
import styles from './index.less'

const menus = [{ name: '指标设计' }, { name: '指标定义' }]
const { OperateItem } = ProTableOperate
const { Option } = Select
const { Item } = Form
const statusArr = ['待开发', '已完成']
const iconArr = ['icon-daikaifa', 'icon-chenggong']

const EditableContext = React.createContext(null)
const EditableRow = ({ index, ...props }) => {
  const [form] = Form.useForm()
  return (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...props} />
      </EditableContext.Provider>
    </Form>
  )
}

const EditableCell = ({
  title,
  editable,
  children,
  dataIndex,
  record,
  handleSave,
  ...restProps
}) => {
  const [editing, setEditing] = useState(false)
  const inputRef = useRef(null)
  const form = useContext(EditableContext)
  useEffect(() => {
    if (editing) {
      inputRef.current?.focus()
    }
  }, [editing])

  const toggleEdit = () => {
    setEditing(!editing)
    form.setFieldsValue({
      [dataIndex]: record[dataIndex],
    })
  }

  const save = async () => {
    try {
      const values = await form.validateFields()
      toggleEdit()
      if (record.version !== values.version) {
        handleSave({ ...record, ...values })
      }
    } catch (errInfo) {
      console.log('Save failed:', errInfo)
    }
  }

  let childNode = children

  if (editable) {
    if (record.versionList && record.versionList.length > 1) {
      childNode = editing ? (
        <Form.Item
          style={{
            margin: 0,
          }}
          name={dataIndex}
          rules={[
            {
              required: true,
              message: '请选择版本号',
            },
          ]}
          initialValue={record.version}
        >
          <Select
            ref={inputRef}
            style={{ width: '100%' }}
            onChange={save}
            onBlur={save}
          >
            {record.versionList.map((item, index) => (
              <Option key={index} value={item}>
                {item}
              </Option>
            ))}
          </Select>
        </Form.Item>
      ) : (
        <div
          className="editable-cell-value-wrap"
          style={{
            paddingRight: 24,
          }}
          onClick={toggleEdit}
        >
          {children}
        </div>
      )
    }
  }

  return <td {...restProps}>{childNode}</td>
}

const getNavTreeDataFunc = list2tree({
  idKey: 'id',
  parentIdKey: 'pid',
  newKey: {
    key: 'id',
    value: 'id',
    title: 'name',
  },
})

export default class IndexDesign extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      treeData: [],
      treeList: [],
      treeDataNew: [],
      loading: false,
      listLoading: false,
      modifyId: null,
      indexSearchStatus: '',
      indexSearchName: '',
      selectedKeys: [],
      query: {},
      versionParams: [],
      ownerArr: [],
      columns: [
        {
          title: '指标名称',
          dataIndex: 'name',
          width: '10%',
          key: 'name',
          render: (text, record) => (
            <span title={text}>{text}</span>
          ),
        },
        {
          title: '业务定义',
          dataIndex: 'businessDef',
          width: '15%',
          key: 'businessDef',
        },
        {
          title: <span>版本 <Tooltip placement="topRight" title="已完成的指标，可通过新增版本进行二次开发"><i className="iconfont icon-yiwentishi" /></Tooltip></span>,
          dataIndex: 'version',
          width: '15%',
          key: 'version',
          editable: true,
          render: (text, { version, versionList }) => (
            <div>
              {version} {versionList.length > 1 && <DownOutlined />}
            </div>
          ),
        },
        // {
        //   title: '数据owner',
        //   dataIndex: 'dataOwnerName',
        //   width: '15%',
        //   key: 'dataOwnerName',
        // },
        {
          title: '状态',
          dataIndex: 'status',
          width: '15%',
          key: 'status',
          render: (text, record) => (
            (record.status || record.status === 0) ? (
              <div className={styles.status_icon}>
                <i
                  className={`iconfont ${iconArr[record.status]}`}
                  style={{ marginRight: '4px' }}
                />
                {statusArr[record.status]}
                {/* {(record.status === 4 || record.status === 6) && (
                  <Popover
                    content={
                      <div>
                        指标计算任务异常，点击{' '}
                        <a>
                          查看详情
                        </a>
                      </div>
                    }
                  >
                    <i className="iconfont icon-yiwentishi" />
                  </Popover>
                )} */}
              </div>
            ) : (<span>--</span>)
          ),
        },
        {
          title: '创建时间',
          dataIndex: 'createTime',
          width: '15%',
          key: 'createTime',
        },
        {
          title: '操作',
          dataIndex: 'operation',
          width: '15%',
          key: 'operation',
          render: (text, record, index) => (
            <ProTableOptions>
              <span onClick={() => this.onCheckIndex(record)} key="check">查看</span>
              {
                (
                  record.status === 0
                )
                  ? <span onClick={() => this.onEditIndex(record)} key="edit">编辑</span> : null
              }
              {
                (
                  record.status === 1
                )
                  ? <span onClick={() => this.onAddVersion(record)} key="change">新增版本</span> : null
              }
              <Popconfirm
                title="你确定要删除这个指标吗？"
                okText="确定"
                cancelText="取消"
                onConfirm={() => this.onDelIndex(record)}
              >
                <span key="delete">
                  删除
                </span>
              </Popconfirm>
            </ProTableOptions>
          ),
        },
      ],
    }

    this.fileForm = React.createRef()
    this.newIndexModalRef = React.createRef()
  }

  componentDidMount() {
    this.getDepartList()
    this.updateList()
  }

  // 获取所有部门
  getDepartList = () => {
    getDepartList().then(
      (res) => {
        this.setState({ ownerArr: res })
      },
      (error) => {
        console.log(error)
      },
    )
  }

  // 新建指标
  onNewIndex = () => {
    const { selectedKeys } = this.state
    this.newIndexModalRef.current.onNewOpen((selectedKeys && selectedKeys.length) ? selectedKeys[0] : null)
  }

  // 查看指标
  onCheckIndex = (record) => {
    this.newIndexModalRef.current.onCheckOpen(record)
  }

  // 编辑指标
  onEditIndex = (record) => {
    this.newIndexModalRef.current.onEditOpen(record)
  }

  // 新增版本
  onAddVersion = (record) => {
    this.setState({ loading: true })
    addIndexVersion({
      analysisDimension: record.analysisDimension,
      businessDef: record.businessDef,
      calculationRule: record.calculationRule,
      unit: record.unit,
      dataOwnerId: record.dataOwnerId,
      indexCatalogId: record.indexCatalogId,
      indexNum: record.indexNum,
      name: record.name,
      remark: record.remark,
      timeGranularity: record.timeGranularity,
    }).then(
      (res) => {
        message.success('新增版本成功')
        const { versionParams } = this.state
        const tempArr = []
        versionParams.map((item) => {
          if (item.indexNum !== record.indexNum) {
            tempArr.push(item)
          }
        })
        this.setState({
          loading: false,
          versionParams: tempArr,
        })
        this.fetchData()
      },
      (error) => {
        this.setState({ loading: false })
      },
    )
  }

  // 删除指标
  onDelIndex = (record) => {
    this.setState({ loading: true })
    delIndex({ id: record.id }).then(
      (res) => {
        message.success('删除指标成功')
        this.fetchData()
        this.setState({ loading: false })
      },
      (error) => {
        console.log(error)
        this.setState({ loading: false })
      },
    )
  }

  // 打开新建目录弹窗
  showFilesModal = (id) => {
    this.fileForm.current?.resetFields()
    this.setState({
      modifyId: null,
      isShowFiles: true,
    }, () => {
      if (id) {
        this.fileForm.current.setFieldsValue({ pid: id })
      }
    })
  }

  // 编辑打开新建目录弹窗
  editFilesModal = (item) => {
    this.fileForm.current?.resetFields()
    this.setState({
      modifyId: item.id,
      isShowFiles: true,
    }, () => {
      if (item) {
        this.fileForm.current.setFieldsValue({
          name: item.name,
        })
      }
    })
  }

  // 创建目录确认
  filesOnOk = () => {
    this.fileForm.current.validateFields().then(values => {
      this.setState({ listLoading: true })
      if (this.state.modifyId) {
        values.id = this.state.modifyId
        editCatalog(values).then(
          (res) => {
            message.success('编辑成功')
            this.setState({
              isShowFiles: false,
              listLoading: false,
              modifyId: null,
            }, () => {
              this.updateList()
            })
          },
          (error) => {
            this.setState({ listLoading: false })
          },
        )
      } else {
        addCatalog(values).then(
          (res) => {
            message.success('新建成功')
            this.setState({
              isShowFiles: false,
              listLoading: false,
            }, () => {
              this.updateList()
            })
          },
          (error) => {
            this.setState({ listLoading: false })
          },
        )
      }
    })
  }

  // 渲染列表节点
  renderTreeNodes = (data) => {
    const tempArr = []
    data.map((item) => {
      const {
        name, id, nodeType,
      } = item
      const defaultIconFun = props => {
        const { selectedKeys } = this.state
        if (selectedKeys && selectedKeys[0] === props.data.key) {
          return props.expanded ? <i className="iconfont-colour2 icon-wenjianjia-dakaihover" /> : <i className="iconfont-colour2 icon-wenjianjia-morenhover" />
        }
        return props.expanded ? <i className="iconfont-colour2 icon-wenjianjia-dakai" /> : <i className="iconfont-colour2 icon-wenjianjia-moren" />
      }
      const tempObj = {
        icon: defaultIconFun,
        key: id,
        nodeType,
      }
      if (item.children) {
        tempObj.children = this.renderTreeNodes(item.children)
      }
      tempObj.title = (
        <HufuTreeTitle
          title={name}
          key={item.id}
          icon
          operations={id === '0' ? [
            <span
              key={`newDir${item.id}`}
              onClick={() => this.showFilesModal(item.id)}
            >
              新建目录
            </span>,
          ] : [
            <span
              key={`newDir${item.id}`}
              onClick={() => this.showFilesModal(item.id)}
            >
              新建目录
            </span>,
            <span
              key={`edit${item.id}`}
              onClick={() => (this.editFilesModal(item))}
            >
              编辑
            </span>,
            <span
              key={`del${item.id}`}
              onClick={() => {
                Modal.confirm({
                  title: '确认要删除这个任务吗？',
                  icon: <ExclamationCircleFilled />,
                  content: '删除后数据将无法恢复，请谨慎操作',
                  okText: '删除',
                  cancelText: '取消',
                  okButtonProps: {
                    danger: true,
                  },
                  onOk: () => {
                    this.setState({ listLoading: true })
                    delCatalog({ id: item.id }).then(
                      (res) => {
                        message.success('删除成功')
                        this.updateList()
                      },
                      (error) => {
                        this.setState({ listLoading: false })
                        console.log(error)
                      },
                    )
                  },
                })
              }}
            >
              删除
            </span>,
          ]}
        />
      )
      tempArr.push(tempObj)
    })
    return tempArr
  }

  fetchData = async () => {
    const {
      indexSearchStatus, indexSearchName, selectedKeys, versionParams,
    } = this.state
    const tempQuery = {}
    if (indexSearchStatus && indexSearchStatus !== '') tempQuery.status = indexSearchStatus
    if (indexSearchName && indexSearchName !== '') tempQuery.name = indexSearchName
    if (selectedKeys && selectedKeys.length > 0) tempQuery.catalogId = selectedKeys[0]
    if (versionParams && versionParams.length) tempQuery.versionParams = versionParams
    this.setState({
      query: tempQuery,
    })
  }

  // 列表选择回调
  onSelect = (selectedKeys) => {
    this.setState({
      selectedKeys,
    }, () => {
      this.fetchData()
    })
  }

  // 新建或编辑成功后的回调
  onCloseCallBack = () => {
    this.fetchData()
  }

  handleSave = (obj) => {
    const { versionParams } = this.state
    const tempArr = versionParams.concat([])
    const item = tempArr.find((param) => param.indexNum === obj.indexNum)
    if (item) {
      item.version = obj.version
    } else {
      tempArr.push({
        indexNum: obj.indexNum,
        version: obj.version,
      })
    }
    this.setState({
      versionParams: tempArr,
    }, () => {
      this.fetchData()
    })
  };

  // 刷新左侧列表
  updateList() {
    this.setState({ listLoading: true })
    listCatalog().then(
      (res) => {
        this.setState({
          treeData: getNavTreeDataFunc(res),
          treeList: res,
          treeDataNew: getNavTreeDataFunc(res),
          listLoading: false,
        })
      },
      (error) => {
        console.log(error)
        this.setState({ listLoading: false })
      },
    )
  }

  render() {
    const {
      treeData, treeList, treeDataNew, selectedKeys, indexSearchStatus, indexSearchName,
      loading, listLoading, ownerArr,
    } = this.state

    const components = {
      body: {
        row: EditableRow,
        cell: EditableCell,
      },
    }
    const columns = this.state.columns.map((col) => {
      if (!col.editable) {
        return col
      }

      return {
        ...col,
        onCell: (record) => ({
          record,
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          handleSave: this.handleSave,
        }),
      }
    })
    return (
      <div className={`${styles.page_content_with_breadcrumb} ${styles.page_content_tabs_height}`}>
        <BreadcrumbBar menu={menus} />
        <div className={styles.page_content}>
          <div className={styles.page_content_left}>
            <ProTree
              showLine
              showSearch
              title="指标目录"
              treeData={treeDataNew}
              renderTreeNodes={this.renderTreeNodes}
              selectedKeys={selectedKeys}
              onSelect={this.onSelect}
              operations={[
                <i
                  key="xinjianwenjianjia"
                  className="iconfont icon-xinjianwenjianjia"
                  onClick={() => this.showFilesModal(null)}
                />,
              ]}
              loading={listLoading}
              ref={(dev) => (this.tree = dev)}
              search={(name) => {
                const searchTree = searchTreeListByName(
                  name,
                  treeList,
                  'name',
                )
                const treeDataNews = getNavTreeDataFunc(
                  searchTree.result,
                )
                this.setState(
                  {
                    treeDataNew: treeDataNews,
                  },
                  () => {
                    this.tree.onExpand(searchTree.fatchIds)
                  },
                )
              }}
            />
          </div>
          <div className={styles.page_content_right}>
            <ProTableOperate
              toggleOperate={false}
              unfolded // 默认展开状态
            >
              <OperateItem align="left">
                <span>状态</span>
                <Select
                  value={indexSearchStatus}
                  onChange={(e) => {
                    this.setState({
                      indexSearchStatus: `${e}`,
                    }, () => {
                      this.fetchData()
                    })
                  }}
                >
                  <Option value="" key="全部">
                    全部
                  </Option>
                  {
                    statusArr.map((item, index) => (
                      <Option value={`${index}`} key={`${index}`}>
                        {item}
                      </Option>
                    ))
                  }
                </Select>
              </OperateItem>
              <OperateItem align="left">
                <InputSearch
                  placeholder="请输入关键词进行搜索"
                  value={indexSearchName}
                  onChange={(e) => {
                    this.setState({
                      indexSearchName: e.target.value,
                    }, () => {
                      this.fetchData()
                    })
                  }}
                  onSearch={this.fetchData}
                />
              </OperateItem>
              <OperateItem itemType="btn">
                {
                  [
                    <Button
                      key="new"
                      onClick={this.onNewIndex}
                      type="primary"
                      loading={loading}
                    >
                      新建指标
                    </Button>,
                  ]
                }
              </OperateItem>
            </ProTableOperate>
            <ProTable
              rowKey="id"
              columns={columns}
              loading={loading}
              query={this.state.query}
              method="post"
              url="/api/v1/index/indexList"
              components={components}
            />
          </div>
        </div>
        <Modal
          title={this.state.modifyId ? '修改目录' : '新建目录'}
          visible={this.state.isShowFiles}
          confirmLoading={listLoading}
          cancelText="取消"
          okText="保存"
          onOk={this.filesOnOk}
          onCancel={() => {
            this.setState({
              isShowFiles: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Form
              ref={this.fileForm}
              labelCol={{ span: 5 }}
              wrapperCol={{ span: 19 }}
              autoComplete="off"
            >
              <Item
                label="目录名称"
                name="name"
                rules={[
                  { required: true, message: '请输入目录名称' },
                ]}
              >
                <Input placeholder="请输入目录名称" />
              </Item>
              {
                !this.state.modifyId && (
                  <Item
                    label="父级目录"
                    name="pid"
                  >
                    <TreeSelect
                      allowClear
                      showSearch
                      getPopupContainer={(triggerNode) => triggerNode.parentNode}
                      // dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                      treeData={treeData}
                      placeholder="请选择父级目录"
                      treeDefaultExpandAll
                      filterTreeNode={(input, treeNode) => treeNode.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                      fieldNames={{
                        label: 'name', value: 'id', children: 'children',
                      }}
                    />
                  </Item>
                )
              }
            </Form>
          </div>
        </Modal>
        <NewIndexModal
          ref={this.newIndexModalRef}
          treeOptions={treeData}
          ownerArr={ownerArr}
          // tableArr={tableArr}
          closeCallBack={this.onCloseCallBack}
        />
      </div>
    )
  }
}
